package spl.manager;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.SocketException;

import spl.utils.GlobalLogger;


public class SocketStream {
	private static final int DEFAULT_MTU = 2048;
	public Socket s;
	/* will hold the stream out of the socket */
	//public BufferedReader in;
	public InputStream inputStream;
	/* will hold a stream from the socket */
	public PrintWriter out;
	public OutputStream outputStream;
	
	SocketStream(Socket streamedSocket) throws UnsupportedEncodingException, IOException {
		this.s = streamedSocket;
		
		// Initialize I/O
		this.inputStream = this.s.getInputStream();
		this.outputStream = this.s.getOutputStream();
		//this.outputStreamWriter = new OutputStreamWriter(this.outputStream);
		//this.in = new BufferedReader(new InputStreamReader(this.inputStream, "UTF-8"));
		this.out = new PrintWriter(new OutputStreamWriter(this.outputStream, "UTF-8"), true);
	}
	
	/**
	 * Reads socket until \r\n is appeared
	 * @return String of line
	 * @throws IOException of socket operation
	 */
	public String readUnbufferredLine() throws IOException {
		String buf = "";
		while (!buf.endsWith("\r\n")) {
			buf += (char) this.inputStream.read();
		}
		
		if (buf.length() >= 2){
			buf = buf.substring(0, buf.length() - 2);			
		}
		
		return buf;
	}
	
	/**
	 * Close all resources with best effort.
	 * On error, we can only log about it.
	 */
	public void freeSocket() {
		
		// Close output steam
		this.out.close();
		// Close socket
		try {
			this.s.close();
		} catch (IOException e) {
			GlobalLogger.getLogger().severe("Couldn't free socket!");
		}
	}
	
	/**
	 * @return the MTU of the interface bounded with this client
	 */
	public int getMTU() {
		try {
			// This can be replaced by looking for the correct inteface, using netmask
			if (null == NetworkInterface.getByInetAddress(this.s.getLocalAddress()))
				return SocketStream.DEFAULT_MTU;
			
			return NetworkInterface.getByInetAddress(this.s.getLocalAddress()).getMTU();
		} catch (SocketException e) {
			return SocketStream.DEFAULT_MTU;
		}
	}
}
